import axios, {AxiosError, AxiosInstance, AxiosResponse} from "axios";
import Global from "@/store/Global";
import router from "@/router/config";
import {ElMessage} from 'element-plus'
import Login from "@/Function/login/Login";

let msgVisible: boolean = false;

class Http {
    http: AxiosInstance

    constructor() {
        this.http = axios.create({
            baseURL: Global.baseURL,
            timeout: 5000
        })
    }

    request(url: string, data: any, method: string = "get", baseURL = Global.baseURL): Promise<AxiosResponse> {
        return new Promise<AxiosResponse>(
            async (resolve, reject) => {
                try {
                    const result = await this.http.request(
                        {
                            method: method,
                            url: baseURL + url,
                            data: data,
                            headers: {
                                Authorization: `Bearer ${Global.token.token}`
                            }
                        }
                    )
                    resolve(result)
                } catch (err: unknown) {
                    const error = err as AxiosError<any, any>;
                    switch (error.response?.status) {
                        case 401:
                            await this.dealError(error, resolve)
                            break;
                        case 403:
                        case 404:
                        case 409:
                            if (!msgVisible) {
                                msgVisible = true
                                ElMessage({
                                    type: 'error',
                                    message: '设备未连接',
                                    onClose: () => {
                                        msgVisible = false
                                    }
                                })
                            }
                            break
                        case 500:
                            if (!msgVisible) {
                                msgVisible = true
                                ElMessage({
                                    type: 'error',
                                    message: error.response?.data.toString(),
                                    onClose: () => {
                                        msgVisible = false
                                    }
                                })
                            }
                            break
                        default:
                            if (!msgVisible) {
                                msgVisible = true
                                ElMessage({
                                    type: 'error',
                                    message: error.response?.data.message,
                                    onClose: () => {
                                        msgVisible = false
                                    }
                                })
                            }
                            break;
                    }
                    if (error.response?.status !== 401 || error.response.data.errorCode !== 11) {
                        reject(error)
                    }
                }
            }
        )
    }

    private async dealError(error: RequestError | AxiosError<any>, resolve: PromiseResolve) {
        //当错误代码为401请求发生错误时的处理方法
        switch (error.response?.data.errorCode) {
            case 10:
                router.push({path: '/login'}).then(r => r)
                if (!msgVisible) {
                    msgVisible = true
                    ElMessage({
                        type: 'error',
                        message: error.response?.data.message,
                        onClose: () => {
                            msgVisible = false
                        }
                    })
                }
                break
            case 11:
                if (Global.token.refreshToken) {
                    try {
                        await Login.postRefreshToken()
                        resolve(await this.http.request(this.analysisErrorURL(error)))
                    } catch (error) {
                        router.push({path: '/Login'}).then()
                    }
                } else {
                    router.push({path: '/Login'}).then()
                }
                break
            case 15:
                // router.push({
                //     path: '/login/resetExpiredPassword',
                //     query: {resetToken: error.response?.data.resetToken}
                // }).then()
                break
            case 16:
                // router.push({path: '/login/resetCertKey', query: {resetToken: error.response?.data.resetToken}}).then()
                break
            default:
                if (!msgVisible) {
                    msgVisible = true
                    ElMessage({
                        type: 'error',
                        message: error.response?.data.message,
                        onClose: () => {
                            msgVisible = false
                        }
                    })
                }
                break
        }
    }

    analysisErrorURL(error: RequestError | AxiosError<any>): RequestParams {
        return Object.assign(<RequestParams>{}, error.response?.config, {
            url: `/${(error.response?.config.url as string).split('/').slice(1).join('/')}`,
            baseURL: (<string>error.response?.config.url).split('/')[0]
        })
    }
}

const
    http: Http = new Http();
export default http;


